Extracting mover positions¶

Binder IPYNB HTML

The following examples show how to find a mover's position at a certain time or for a certain time span.

In [1]:
import pandas as pd
import geopandas as gpd
from geopandas import GeoDataFrame, read_file
from shapely.geometry import Point, LineString, Polygon
from datetime import datetime, timedelta
import movingpandas as mpd

import warnings
warnings.filterwarnings('ignore')

mpd.show_versions()
MovingPandas 0.9.rc2

SYSTEM INFO
-----------
python     : 3.7.12 | packaged by conda-forge | (default, Oct 26 2021, 05:37:49) [MSC v.1916 64 bit (AMD64)]
executable : E:\Anaconda\envs\mpd-ex\python.exe
machine    : Windows-10-10.0.19041-SP0

GEOS, GDAL, PROJ INFO
---------------------
GEOS       : None
GEOS lib   : None
GDAL       : 3.2.1
GDAL data dir: None
PROJ       : 7.2.0
PROJ data dir: E:\Anaconda\envs\mpd-ex\Library\share\proj

PYTHON DEPENDENCIES
-------------------
geopandas  : 0.10.2
pandas     : 1.3.5
fiona      : 1.8.18
numpy      : 1.21.5
shapely    : 1.7.1
rtree      : 0.9.7
pyproj     : 3.1.0
matplotlib : 3.5.1
mapclassify: 2.4.3
geopy      : 2.2.0
holoviews  : 1.14.6
hvplot     : 0.7.3
geoviews   : 1.9.2

First, let's create a basic trajectory:

In [2]:
df = pd.DataFrame([
  {'geometry':Point(0,0), 't':datetime(2018,1,1,12,0,0)},
  {'geometry':Point(6,0), 't':datetime(2018,1,1,12,6,0)},
  {'geometry':Point(6,6), 't':datetime(2018,1,1,12,10,0)},
  {'geometry':Point(9,9), 't':datetime(2018,1,1,12,15,0)}
]).set_index('t')
gdf = GeoDataFrame(df, crs=31256)
toy_traj = mpd.Trajectory(gdf, 1)
toy_traj
Out[2]:
Trajectory 1 (2018-01-01 12:00:00 to 2018-01-01 12:15:00) | Size: 4 | Length: 16.2m
Bounds: (0.0, 0.0, 9.0, 9.0)
LINESTRING (0 0, 6 0, 6 6, 9 9)

Extracting a mover's position at a certain time¶

In [3]:
help(mpd.Trajectory.get_position_at)
Help on function get_position_at in module movingpandas.trajectory:

get_position_at(self, t, method='interpolated')
    Compute and return position at time t.
    
    Parameters
    ----------
    t : datetime.datetime
        Timestamp to extract a row for
    method : str
        Interpolation method
    
    Returns
    -------
    shapely Point
        Position at time t
    
    Examples
    --------
    If the trajectory contains a position at the given timestamp, it is
    returned:
    
    >>> traj.get_position_at(datetime(2018, 1, 1, 12, 6))
    Point (6 0)
    
    If there is no trajectory position for the given timestamp, the default
    behaviour is to interpolate the location:
    
    >>> traj.get_position_at(datetime(2018, 1, 1, 12, 9))
    POINT (6 4.5)
    
    To get the trajectory position closest to the given timestamp, specify
    method='nearest':
    
    >>> traj.get_position_at(datetime(2018, 1, 1, 12, 9), method='nearest')
    POINT (6 6)

When we call this method, the resulting point is directly rendered:

In [4]:
toy_traj.get_position_at(datetime(2018,1,1,12,6,0), method="nearest")    
Out[4]:

To see its coordinates, we can look at the print output:

In [5]:
print(toy_traj.get_position_at(datetime(2018,1,1,12,6,0), method="nearest"))
POINT (6 0)

The method parameter describes what the function should do if there is no entry in the trajectory GeoDataFrame for the specified timestamp.

For example, there is no entry at 2018-01-01 12:07:00

In [6]:
toy_traj.df
Out[6]:
geometry
t
2018-01-01 12:00:00 POINT (0.000 0.000)
2018-01-01 12:06:00 POINT (6.000 0.000)
2018-01-01 12:10:00 POINT (6.000 6.000)
2018-01-01 12:15:00 POINT (9.000 9.000)
In [7]:
t = datetime(2018,1,1,12,7,0)
print(toy_traj.get_position_at(t, method="nearest"))
print(toy_traj.get_position_at(t, method="interpolated"))
print(toy_traj.get_position_at(t, method="ffill")) # from the previous row
print(toy_traj.get_position_at(t, method="bfill")) # from the following row
POINT (6 0)
POINT (6 1.5)
POINT (6 0)
POINT (6 6)
In [8]:
point = toy_traj.get_position_at(t, method="interpolated")
df = pd.DataFrame([{'id': toy_traj.id, 'geometry': point, 't': t}])
gdf = GeoDataFrame(df, crs=toy_traj.crs)

ax = toy_traj.plot()
gdf.plot(ax=ax, color='red', markersize=100)
Out[8]:
<AxesSubplot:>
In [9]:
ax = toy_traj.plot()

Extracting trajectory segments based on time¶

First, let's extract the trajectory segment for a certain time period:

In [10]:
help(mpd.Trajectory.get_segment_between)
Help on function get_segment_between in module movingpandas.trajectory:

get_segment_between(self, t1, t2)
    Return Trajectory segment between times t1 and t2.
    
    Parameters
    ----------
    t1 : datetime.datetime
        Start time for the segment
    t2 : datetime.datetime
        End time for the segment
    
    Returns
    -------
    Trajectory
        Extracted trajectory segment

In [11]:
segment = toy_traj.get_segment_between(datetime(2018,1,1,12,6,0), datetime(2018,1,1,12,12,0))
print(segment)
Trajectory 1_2018-01-01 12:06:00 (2018-01-01 12:06:00 to 2018-01-01 12:10:00) | Size: 2 | Length: 6.0m
Bounds: (6.0, 0.0, 6.0, 6.0)
LINESTRING (6 0, 6 6)
In [12]:
ax = toy_traj.plot()
segment.plot(ax=ax, color='red', linewidth=5)
Out[12]:
<AxesSubplot:>

Extracting trajectory segments based on geometry (i.e. clipping)¶

Now, let's extract the trajectory segment that intersects with a given polygon:

In [13]:
xmin, xmax, ymin, ymax = 2, 8, -10, 5
polygon = Polygon([(xmin, ymin), (xmin, ymax), (xmax, ymax), (xmax, ymin), (xmin, ymin)])
polygon
Out[13]:
In [14]:
polygon_gdf = GeoDataFrame(pd.DataFrame([{'geometry':polygon, 'id':1}]), crs=31256)
In [15]:
help(mpd.Trajectory.clip)
Help on function clip in module movingpandas.trajectory:

clip(self, polygon, point_based=False)
    Return trajectory segments clipped by the given polygon.
    
    By default, the trajectory's line representation is clipped by the
    polygon. If pointbased=True, the trajectory's point representation is
    used instead, leading to shorter segments.
    
    Parameters
    ----------
    polygon : shapely Polygon
        Polygon to clip with
    point_based : bool
        Clipping method
    
    Returns
    -------
    TrajectoryCollection
        Clipped trajectory segments

In [16]:
intersections = toy_traj.clip(polygon)
intersections
Out[16]:
TrajectoryCollection with 1 trajectories
In [17]:
ax = toy_traj.plot()
polygon_gdf.plot(ax=ax, color='lightgray')
intersections.plot(ax=ax, color='red', linewidth=5, capstyle='round')
Out[17]:
<AxesSubplot:>
In [ ]: